package com.aizuda.encrypt.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.text.NamingCase;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.aizuda.encrypt.constant.EncryptConstant;
import com.aizuda.encrypt.entity.ColumnRule;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

/**
 * 规则工具类
 *
 * @author nn200433
 * @date 2024-03-27 11:47:04
 */
@Slf4j
public class RuleUtil {

    /**
     * 获取表规则
     *
     * @param key     键
     * @param value   价值
     * @param ruleMap 规则映射
     * @author nn200433
     */
    public static void findTableRule(String key, Object value, Map<String, Map<String, ColumnRule>> ruleMap) {
        final Matcher matcher = EncryptConstant.PROPERTIES_TABLE_RULE_PERCENT_REGEX.matcher(key);
        if (!matcher.matches()) {
            return;
        }
        final String tableName   = matcher.group("tableName");
        final String columnName  = matcher.group("columnName");
        final String entityField = fieldNameFmt(matcher.group("entityField"));
        log.debug("---> [读取配置] {}.{}.{} = {}", tableName, columnName, entityField, value);
        Map<String, ColumnRule> columnRuleMap = ruleMap.get(tableName);
        if (CollUtil.isEmpty(columnRuleMap)) {
            columnRuleMap = new HashMap<String, ColumnRule>();
            ruleMap.put(tableName, columnRuleMap);
        }
        ColumnRule columnRule = columnRuleMap.get(columnName);
        if (null == columnRule) {
            columnRule = new ColumnRule();
            columnRuleMap.put(columnName, columnRule);
        }
        try {
            final Field    field      = ReflectUtil.getField(ColumnRule.class, entityField);
            final Class<?> clzType    = field.getType();
            final String   methodName = StrUtil.upperFirstAndAddPre(entityField, "set");
            final Method   invokeSet  = ReflectUtil.getMethodByName(ColumnRule.class, methodName);
            invokeSet.invoke(columnRule, Convert.convert(clzType, value));
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 字段名格式处理
     *
     * @param str str
     * @return {@link String }
     * @author nn200433
     */
    private static String fieldNameFmt(String str) {
        return NamingCase.toCamelCase(str, CharPool.DASHED);
    }

}
